package ${controllerPackage};

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import ${class};
import ${vopackage}.*;
import ${mapperPackage}.${mapper};

@RestController
public class ${class_s}Controller {

    @Autowired
    public ${mapper} ${mapper_ss};

    @GetMapping("/${class_ss}/datagrid")
    public DataGridVo dataGrid(@RequestParam(defaultValue="1") int page, @RequestParam(defaultValue="10") int rows,
        ${class_s}Vo vo) {
        List<${class_s}> list = ${mapper_ss}.findByVo(vo);
        int total = ${mapper_ss}.findCountByVo(vo);
        return new DataGridVo(list, total);
    }

    <#if save>
    @PostMapping("/${class_ss}/save")
    public Map<String,Object> save(${class_s} ${class_ss}){
        <#list server_save_assignment as ssa>${ssa}</#list>
        ${mapper_ss}.save(${class_ss});
        Map<String,Object> map = new HashMap<>();
        map.put("success", true);
        return map;
    }
    </#if>

    <#if update>
    @PostMapping("/${class_ss}/update")
    public Map<String,Object> update(${class_s} ${class_ss}){
        <#list server_update_assignment as sua>${sua}</#list>
        ${mapper_ss}.update(${class_ss});
        Map<String,Object> map = new HashMap<>();
        map.put("success", true);
        return map;
    }
    </#if>

    <#if findById>
    @GetMapping("/${class_ss}/findById")
    public ${class_s} findById(${findByIdProperty.javatype} ${findByIdProperty.name}){
        return ${mapper_ss}.${findByIdProperty.id}(${findByIdProperty.name});
    }
    </#if>

    <#if deleteById>
    @GetMapping("/${class_ss}/deleteById")
    public Map<String,Object> delete(${deleteByIdProperty.javatype} ${deleteByIdProperty.name}){
        <#list middleProperties as m>
        ${mapper_ss}.remove${m.op_s}s(${deleteByIdProperty.name});
        </#list>
        ${mapper_ss}.${deleteByIdProperty.id}(${deleteByIdProperty.name});
        Map<String,Object> map = new HashMap<>();
        map.put("success", true);
        return map;
    }
    </#if>

    <#if deleteByIds>
    @GetMapping("/${class_ss}/deleteByIds")
    public Map<String,Object> delete(@RequestParam ${deleteByIdsProperty.javatype} ${deleteByIdsProperty.name}){
        <#list middleProperties as m>
        for(${deleteByIdsProperty.boxedType} p : ${deleteByIdsProperty.name}){
            ${mapper_ss}.remove${m.op_s}s(p);
        }
        </#list>
        ${mapper_ss}.${deleteByIdsProperty.id}(${deleteByIdsProperty.name});
        Map<String,Object> map = new HashMap<>();
        map.put("success", true);
        return map;
    }
    </#if>
    
    <#if useAdapter>
    @GetMapping("/${class_ss}/findAllCombo")
    public List<Map<String,Object>> findAllValueText(){
        List<${class_s}> list = ${mapper_ss}.findAll();
        List<Map<String,Object>> nlist = new ArrayList<>();
        for(${class_s} s:list){
            Map<String,Object> o = new HashMap<>();
            o.put("value", s.${valueFieldGetMethod}());
            o.put("text", s.${textFieldGetMethod}());
            nlist.add(o);
        }
        return nlist;
    }
    
    @GetMapping("/${class_ss}/findAllKV")
    public Map<String,Object> findAllKV(){
        List<${class_s}> list = ${mapper_ss}.findAll();
        Map<String,Object> map = new HashMap<>();
        for(${class_s} s:list){
            map.put(String.valueOf(s.${valueFieldGetMethod}()), s.${textFieldGetMethod}());
        }
        return map;
    }

    @GetMapping("/${class_ss}/findAllTree")
    public List<TreeVo> findAllTree(){
        <#if treeAdapter>
        List<TreeVo> all = ${mapper_ss}.findAll()
            .stream().map(c->new TreeVo(c.${valueFieldGetMethod}(),c.${textFieldGetMethod}(),c.${pidFieldGetMethod}())).collect(Collectors.toList());
        List<TreeVo> root = all.stream().filter(c->c.getPid()==${pidTopValue}).collect(Collectors.toList());
        Map<Integer, TreeVo> map = all.stream().collect(Collectors.toMap(c -> c.getId(), c -> c));
        all.stream().filter(c->c.getPid()!=${pidTopValue}).forEach(c->{
            TreeVo parent = map.get(c.getPid());
            if(parent!=null) {
                parent.getChildren().add(c);
            }
        });
        return root;
        <#else>
        return ${mapper_ss}.findAll().stream().map(c->new TreeVo(c.${valueFieldGetMethod}(),c.${textFieldGetMethod}(),0)).collect(Collectors.toList());
        </#if>
    }

    </#if>
    <#list middleProperties as m>
    @PostMapping("/${class_ss}/modify${m.op_s}s")
    public Map<String,Object> modify${m.op_s}s(${id_class} ${m.ownVar}, @RequestParam List<${id_class_boxed}> ${m.oppositeVar}s){
        ${mapper_ss}.remove${m.op_s}s(${m.ownVar});
        for(${id_class_boxed} ${m.oppositeVar}:${m.oppositeVar}s){
            ${mapper_ss}.insert${m.op_s}(${m.ownVar}, ${m.oppositeVar});
        }
        Map<String,Object> map = new HashMap<>();
        map.put("success", true);
        return map;
    }

    @GetMapping("/${class_ss}/get${m.op_s}s")
    public List<${id_class_boxed}> get${m.op_s}s(${id_class} ${m.ownVar}){
        return ${mapper_ss}.get${m.op_s}s(${m.ownVar});
    }

    </#list>

}